import type { RequestConfig, RequestOptions, RequestFileConfig, Server } from './types';
import { request, createRequest } from './request';

import { useEnv } from '@/hooks/core/useEnv';

import { ServerConfig, ServerRequestHook } from './server/index';
import { CodeEnum } from './requestCode';
import { isObject } from '../is';
import { useUserStoreWithOut } from '@/store/modules/user';
import { Toast } from '@/utils/index';
import { navigateBack, navigateTo } from '@/router';
import { logManager } from '../log';

const { getEnv } = useEnv();
export class RequestTransform extends request {

  static pending: request[] = []
  static setPend(item: request) {
    RequestTransform.pending.push(item)
  }
  static removePend(item: request) {
    const index = RequestTransform.pending.findIndex(v => v === item)
    if (index !== -1) RequestTransform.pending.splice(index, 1)
  }

  constructor(op: { config: RequestConfig; options?: RequestOptions }) {
    super(op);
    RequestTransform.setPend(this)
  }

  /**
   * 处理请求数据。如果数据不是预期格式，可直接抛出错误
   */
  async requestHook(): Promise<any> | never {
    // 文件处理
    switch (this.config.server) {
      case 'server':
        return ServerRequestHook(this);
    }
    const ErrorMsg = (this.result?.data?.msg || JSON.stringify(this.result?.data)) as string;
    if (this.result && this.result.statusCode === 200) {
      const resultData = this.result.data;
      const { code, data, msg } = isObject(resultData) ? resultData : JSON.parse(resultData);
      if (code === CodeEnum.notLogin) {
        // Toast('用户未登录');
        /** 丢失登录状态 取消其他请求 */
        RequestTransform.pending.forEach(v => {
          if (v !== this) {
            v.requestTask?.abort();
          }
        })
        RequestTransform.pending = []
        useUserStoreWithOut().resetApp();
        throw new Error(ErrorMsg);
      }

      if (code === CodeEnum.layUp || code === CodeEnum.disable) {
        uni.showModal({
          title: '提示',
          content: msg,
          showCancel: false,
          success: () => navigateBack(),
        });
        throw new Error(ErrorMsg);
      }

      if (code === CodeEnum.modalMsg) {
        uni.showModal({
          title: '异常提示',
          content: msg,
          showCancel: false,
          confirmText: '确定',
        });
        throw new Error(ErrorMsg);
      }

      if (code === CodeEnum.special) return data;

      if (code === CodeEnum.success) {
        RequestTransform.removePend(this)
        return this.options?.isRequestTransform ? this.result.data : data;
      }

      Toast(msg);
    }

    logManager.error(ErrorMsg);
    throw new Error(ErrorMsg);
  }

  /**
   * 请求之前处理 config
   */
  async beforeRequestHook() {
    // 文件上传处理
    if (this.config.files && !this.config.url) {
      const server = this.config.server || getEnv('REQUEST_FILE_SERVER');
      switch (server) {
        case 'server':
          this.config = (await ServerConfig(this.config as RequestFileConfig)) as RequestConfig;
          break;
      }
      this.config.server = server as Server;
      return;
    }
  }

}

export const defHttp = createRequest();
